//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_BSP_LOADER_H__
#define __ELASTOS_BSP_LOADER_H__

EXTERN_C_BEGIN

typedef struct PackageInfo
{
    uint32_t        uReserved;
    BootModule      *modules;
    uint_t          uNumberOfModules;
    size_t          uPackageSize;
    char            *szCommandLine;
} PackageInfo;

typedef void (__cdecl *ENTRYPOINT)(...);

#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
#define IMAGE_OS2_SIGNATURE                 0x454E      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x454C      // LE
#define IMAGE_NT_SIGNATURE                  0x00004550  // PE00

typedef struct DECL_PACKED _IMAGE_DOS_HEADER {  // DOS .EXE header
    USHORT e_magic;             // Magic number
    USHORT e_cblp;              // Bytes on last page of file
    USHORT e_cp;                // Pages in file
    USHORT e_crlc;              // Relocations
    USHORT e_cparhdr;           // Size of header in paragraphs
    USHORT e_minalloc;          // Minimum extra paragraphs needed
    USHORT e_maxalloc;          // Maximum extra paragraphs needed
    USHORT e_ss;                // Initial (relative) SS value
    USHORT e_sp;                // Initial SP value
    USHORT e_csum;              // Checksum
    USHORT e_ip;                // Initial IP value
    USHORT e_cs;                // Initial (relative) CS value
    USHORT e_lfarlc;            // File address of relocation table
    USHORT e_ovno;              // Overlay number
    USHORT e_res[4];            // Reserved words
    USHORT e_oemid;             // OEM identifier (for e_oeminfo)
    USHORT e_oeminfo;           // OEM information; e_oemid specific
    USHORT e_res2[10];          // Reserved words
    LONG   e_lfanew;            // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

//
// File header format.
//
typedef struct DECL_PACKED _IMAGE_FILE_HEADER {
    USHORT  Machine;
    USHORT  NumberOfSections;
    ULONG   TimeDateStamp;
    ULONG   PointerToSymbolTable;
    ULONG   NumberOfSymbols;
    USHORT  SizeOfOptionalHeader;
    USHORT  Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define IMAGE_SIZEOF_FILE_HEADER             20

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_MINIMAL_OBJECT            0x0010  // Reserved.
#define IMAGE_FILE_UPDATE_OBJECT             0x0020  // Reserved.
#define IMAGE_FILE_16BIT_MACHINE             0x0040  // 16 bit word machine.
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_PATCH                     0x0400  // Reserved.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I860              0x14d   // Intel 860.
#define IMAGE_FILE_MACHINE_I386              0x14c   // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x162   // MIPS little-endian, 0540 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x166   // MIPS little-endian
#define IMAGE_FILE_MACHINE_ALPHA             0x184   // Alpha_AXP
#define IMAGE_FILE_MACHINE_ARM               0x1c0   // Arm 7

//
// Directory format.
//
typedef struct DECL_PACKED _IMAGE_DATA_DIRECTORY {
    ULONG   VirtualAddress;
    ULONG   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

//
// Optional header format.
//
typedef struct DECL_PACKED _IMAGE_OPTIONAL_HEADER {
    // Standard fields.
    USHORT  Magic;
    UCHAR   MajorLinkerVersion;
    UCHAR   MinorLinkerVersion;
    ULONG   SizeOfCode;
    ULONG   SizeOfInitializedData;
    ULONG   SizeOfUninitializedData;
    ULONG   AddressOfEntryPoint;
    ULONG   BaseOfCode;
    ULONG   BaseOfData;

    // NT additional fields.
    ULONG   ImageBase;
    ULONG   SectionAlignment;
    ULONG   FileAlignment;
    USHORT  MajorOperatingSystemVersion;
    USHORT  MinorOperatingSystemVersion;
    USHORT  MajorImageVersion;
    USHORT  MinorImageVersion;
    USHORT  MajorSubsystemVersion;
    USHORT  MinorSubsystemVersion;
    ULONG   Reserved1;
    ULONG   SizeOfImage;
    ULONG   SizeOfHeaders;
    ULONG   CheckSum;
    USHORT  Subsystem;
    USHORT  DllCharacteristics;
    ULONG   SizeOfStackReserve;
    ULONG   SizeOfStackCommit;
    ULONG   SizeOfHeapReserve;
    ULONG   SizeOfHeapCommit;
    ULONG   LoaderFlags;
    ULONG   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER        28
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER         224

typedef struct DECL_PACKED _IMAGE_NT_HEADERS {
    ULONG Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

typedef struct BootInfo {
    uint32_t WriteMagic;        // Set Write Flash signature, 0x3BADBAD3 is the
                                //  magic number which is a legacy form Elame
    uint32_t FlashSectorSize;   // the size of section in flash
    uint32_t FlashOffset;       // the flash position of elastos.img
    uint32_t ImageOffset;       // the ram positon of elastos.img
    uint32_t ImageSize;         // the size of elastos.img
} BootInfo;

#define ENTRYPOINT(_b_) \
        ((IMAGE_NT_HEADERS *)((_b_) + ((IMAGE_DOS_HEADER *)(_b_))->e_lfanew)) \
            ->OptionalHeader.AddressOfEntryPoint
#define IMAGEBASE(_b_) \
        ((IMAGE_NT_HEADERS *)((_b_) + ((IMAGE_DOS_HEADER *)(_b_))->e_lfanew)) \
            ->OptionalHeader.ImageBase

#define IMAGESIZE(_b_) \
        ((IMAGE_NT_HEADERS *)((_b_) + ((IMAGE_DOS_HEADER *)(_b_))->e_lfanew)) \
            ->OptionalHeader.SizeOfImage

#define NTSIGNATURE(_b_) \
        ((IMAGE_NT_HEADERS *)((_b_) + ((IMAGE_DOS_HEADER *)(_b_))->e_lfanew)) \
            ->Signature

#define PMODINFO_HEADER(_b_) \
        ((MODINFO_HEADER *)(((_b_)) + (sizeof(IMAGE_DOS_HEADER) - \
            sizeof(MODINFO_HEADER))))

int main(void);
void C_main(void);

void OutputByte(unsigned char c);

#define queryflag   '?'
#define startflag   '<'
#define endflag     '>'
#define noteflag    '!'
#define debugflag   'x'
#define writeflag   'w'
#define eraseflag   'e'

EXTERN_C_END

#endif // __ELASTOS_BSP_LOADER_H__
